package core;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.util.ArrayList;

import javax.swing.ImageIcon;

/**
 * @author Arno de Jager
 *
 */
public class Map implements Drawable {
	private static final ImageIcon normalBackground = new ImageIcon(Map.class.getResource("../images/background.gif"));
	private static final ImageIcon snowBackground = new ImageIcon(Map.class.getResource("../images/background-snow.gif"));
	
	private ArrayList<ArrayList<Point2D.Double>> routes;
	private ImageIcon background = normalBackground;
	
	private Base base;
	private	ArrayList<Polygon> polygonArray = new ArrayList<Polygon>();
	private int ID;
	/**
	 * Breedte van de weg
	 */
	public static final int wayWidth = 35;

	public Map( Base base, ArrayList<ArrayList<Point2D.Double>> routes, int ID )
	{
		this.base = base;
		this.routes = routes;
		this.ID = ID;
	}
	
	public int getID(){
		return ID;
	}
	
	public void setBase( Base b )
	{
		this.base = b;
	}

	/**
	 * @return the routes
	 */
	public ArrayList<ArrayList<Point2D.Double>> getRoutes() {
		return routes;
	}

	/**
	 * @return the background
	 */
	public ImageIcon getBackground() {
		return background;
	}

	/**
	 * @return the base
	 */
	public Base getBase() {
		return base;
	}

	/**
	 * Teken achtergrond en routes
	 * @see core.Drawable#draw(java.awt.Graphics, java.awt.Rectangle, java.awt.Component)
	 */
	public void draw(Graphics g, Rectangle area, Component c) {
		Graphics2D g2 = (Graphics2D)g;
		
		// Teken achtergrond
		g.drawImage( background.getImage(), 0, 0, area.width, area.height, c );
		
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		// Teken routes
		for( ArrayList<Point2D.Double> route : routes ) {
			
			if ( route.size() == 0 )
				continue;
			
			// Teken punten
			Point2D.Double prevPoint = null;
			
			
		//tekenen van cirkels
		for( Point2D.Double p : route ) {
			g2.setColor( new Color(107, 130, 139) );
			g2.fillOval((int)p.x-6, (int)p.y-6, (int)wayWidth, (int)wayWidth);
			g2.setColor( Color.WHITE );
			g2.drawOval((int)p.x-6, (int)p.y-6, (int)wayWidth, (int)wayWidth);
		}
		
		for( Point2D.Double p : route ) {
			if ( prevPoint != null  ){
				
				//controle op rechte stukken, anders niet tekenen
				if(prevPoint.y == p.y || prevPoint.x == p.x){
					Point2D.Double po = new Point2D.Double();
					Point2D.Double prevPoint2 = new Point2D.Double();
					po.x = p.x +12;
					po.y = p.y +12;
					prevPoint2.x = prevPoint.x + 12;
					prevPoint2.y = prevPoint.y +12;
					
					if(prevPoint.y == p.y){
						//boven /onder balk
						int afwijking = 17;
						int afwijkingk = 0;
						//tekenen van witte buitenlijnen.
						g2.setColor( Color.WHITE );
						g2.drawLine( (int)(prevPoint2.x + afwijkingk), (int)(prevPoint2.y+afwijking), (int)(po.x + afwijkingk), (int)(po.y + afwijking) );
						g2.drawLine( (int)(prevPoint2.x - afwijkingk-1), (int)(prevPoint2.y-afwijking-1), (int)(po.x - afwijkingk-1), (int)(po.y - afwijking-1) );
						
					}else{
						int afwijking = 0;
						int afwijkingk = 17;
						//tekenen van witte buitenlijnen.
						g2.setColor( Color.WHITE );
						g2.drawLine( (int)(prevPoint2.x + afwijkingk), (int)(prevPoint2.y+afwijking), (int)(po.x + afwijkingk), (int)(po.y + afwijking) );
						g2.drawLine( (int)(prevPoint2.x - afwijkingk-1), (int)(prevPoint2.y-afwijking-1), (int)(po.x - afwijkingk-1), (int)(po.y - afwijking-1) );
						
					}
				}
			}
			prevPoint = p;
		}
				
			
			for( Point2D.Double p : route ) {
				
				// We tekenen de route per 2 punten
				if ( prevPoint != null )
				{	
					g2.setColor( new Color(107, 130, 139) );
					
					Polygon polygon = new Polygon();
					//punten kopieren
					Point2D.Double po = new Point2D.Double();
					Point2D.Double prevPoint2 = new Point2D.Double();
					//afwijking toepassen
					po.x = p.x +12;
					po.y = p.y +12;
					prevPoint2.x = prevPoint.x + 12;
					prevPoint2.y = prevPoint.y +12;
					
					if(prevPoint.y == p.y || prevPoint.x == p.x){
						//rechte blok, andere negeren.

						if(prevPoint.y == p.y){
							//boven /onder balk
							int afwijking = 17;
							int afwijkingk = 0;

							g2.setColor( new Color(107, 130, 139) );
							polygon.addPoint((int)(prevPoint2.x + afwijkingk), (int)(prevPoint2.y+afwijking) );
							polygon.addPoint((int)(prevPoint2.x - afwijkingk), (int)(prevPoint2.y-afwijking));
							polygon.addPoint((int)(po.x - afwijkingk), (int)(po.y - afwijking));
							polygon.addPoint((int)(po.x + afwijkingk), (int)(po.y + afwijking));
							g2.fillPolygon( polygon );
							
						}else{
							int afwijking = 0;
							int afwijkingk = 17;
							
							g2.setColor( new Color(107, 130, 139) );
							polygon.addPoint((int)(prevPoint2.x + afwijkingk), (int)(prevPoint2.y+afwijking) );
							polygon.addPoint((int)(prevPoint2.x - afwijkingk), (int)(prevPoint2.y-afwijking));
							polygon.addPoint((int)(po.x - afwijkingk), (int)(po.y - afwijking));
							polygon.addPoint((int)(po.x + afwijkingk), (int)(po.y + afwijking));
							g2.fillPolygon( polygon );
														
						}
					}
					//weg toevoegen voor bounding layout later te kunnen bepalen.
					polygonArray.add(polygon);

				}
				prevPoint = p;
			}
		}
		
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
		
		// Teken base
		if ( base != null )
			base.draw( g, area, c );
	}
	
	
	public ArrayList<Polygon> getPolygonArray(){
		return polygonArray;
	}
	
	public void toggleSnow(boolean t){
		if(t){
			//aanzetten
			background = snowBackground;
		}else{
			background = normalBackground;
		}
	}
	

}
